home *** CD-ROM | disk | FTP | other *** search
/ Cre@te Online 2000 December / Cre@teOnline CD05.iso / MacSoft / XML ConsoleMax.sea / XML ConsoleMax / Required / xml4j.jar / com / ibm / xml / internal / DFAContentModel.class (.txt) < prev    next >
Encoding:
Java Class File  |  1999-08-30  |  6.3 KB  |  375 lines

  1. package com.ibm.xml.internal;
  2.  
  3. import com.ibm.xml.framework.ContentModel;
  4. import com.ibm.xml.framework.ContentSpecNode;
  5. import com.ibm.xml.framework.ElementDeclPool;
  6. import com.ibm.xml.framework.InsertableElementsInfo;
  7. import com.ibm.xml.framework.StringPool;
  8. import com.ibm.xml.framework.XMLErrorHandler;
  9.  
  10. class DFAContentModel implements ContentModel {
  11.    private static final String fEpsilonString = "<<CMNODE_EPSILON>>";
  12.    private static final String fEOCString = "<<CMNODE_EOC>>";
  13.    private static final boolean DEBUG_VALIDATE_CONTENT = false;
  14.    private ElementDeclPool fDeclPool;
  15.    private int fElementIndex;
  16.    private int[] fElemMap;
  17.    private int fElemMapSize;
  18.    private int fEOCIndex;
  19.    private int fEOCPos;
  20.    private int fEpsilonIndex;
  21.    private XMLErrorHandler fErrHandler;
  22.    private boolean[] fFinalStateFlags;
  23.    private CMStateSet[] fFollowList;
  24.    private CMNode fHeadNode;
  25.    private int fLeafCount;
  26.    private CMLeaf[] fLeafList;
  27.    private ContentSpecNode fSpecNode;
  28.    private StringPool fStringPool;
  29.    private int[][] fTransTable;
  30.    private int fTransTableSize;
  31.    private boolean fEmptyContentIsValid = false;
  32.  
  33.    public DFAContentModel(int var1, StringPool var2, ElementDeclPool var3) throws CMException {
  34.       this.fElementIndex = var1;
  35.       this.fDeclPool = var3;
  36.       this.fStringPool = var2;
  37.       this.fEpsilonIndex = this.fStringPool.addSymbol("<<CMNODE_EPSILON>>");
  38.       this.fEOCIndex = this.fStringPool.addSymbol("<<CMNODE_EOC>>");
  39.       this.fSpecNode = new ContentSpecNode();
  40.       this.fDeclPool.getContentSpecNode(this.fDeclPool.getContentSpec(this.fElementIndex), this.fSpecNode);
  41.       this.buildDFA();
  42.    }
  43.  
  44.    public int validateContent(int var1, int[] var2) throws CMException {
  45.       if (var1 == 0) {
  46.          return this.fEmptyContentIsValid ? -1 : 0;
  47.       } else {
  48.          int var3 = 0;
  49.  
  50.          for(int var4 = 0; var4 < var1; ++var4) {
  51.             int var5 = var2[var4];
  52.  
  53.             int var6;
  54.             for(var6 = 0; var6 < this.fElemMapSize && this.fElemMap[var6] != var5; ++var6) {
  55.             }
  56.  
  57.             if (var6 == this.fElemMapSize) {
  58.                return var4;
  59.             }
  60.  
  61.             var3 = this.fTransTable[var3][var6];
  62.             if (var3 == -1) {
  63.                return var4;
  64.             }
  65.          }
  66.  
  67.          if (!this.fFinalStateFlags[var3]) {
  68.             return var1;
  69.          } else {
  70.             return -1;
  71.          }
  72.       }
  73.    }
  74.  
  75.    public int whatCanGoHere(boolean var1, InsertableElementsInfo var2) throws CMException {
  76.       int var3 = 0;
  77.  
  78.       for(int var4 = 0; var4 < var2.insertAt; ++var4) {
  79.          int var5 = var2.curChildren[var4];
  80.  
  81.          int var6;
  82.          for(var6 = 0; var6 < this.fElemMapSize && this.fElemMap[var6] != var5; ++var6) {
  83.          }
  84.  
  85.          if (var6 == this.fElemMapSize) {
  86.             return var4;
  87.          }
  88.  
  89.          var3 = this.fTransTable[var3][var6];
  90.          if (var3 == -1) {
  91.             return var4;
  92.          }
  93.       }
  94.  
  95.       int var8 = var3;
  96.       var2.canHoldPCData = false;
  97.       var2.isValidEOC = this.fFinalStateFlags[var3];
  98.       var2.resultsCount = this.fElemMapSize;
  99.       if (var2.results == null || var2.results.length < var2.resultsCount) {
  100.          var2.results = new boolean[var2.resultsCount];
  101.       }
  102.  
  103.       if (var2.possibleChildren == null || var2.possibleChildren.length < var2.resultsCount) {
  104.          var2.possibleChildren = new int[var2.resultsCount];
  105.       }
  106.  
  107.       for(int var9 = 0; var9 < this.fElemMapSize; ++var9) {
  108.          var2.possibleChildren[var9] = this.fElemMap[var9];
  109.          var2.results[var9] = this.fTransTable[var8][var9] != -1;
  110.       }
  111.  
  112.       if (var1) {
  113.          for(int var7 = 0; var7 < var2.resultsCount; ++var7) {
  114.             if (var2.results[var7]) {
  115.                var2.curChildren[var2.insertAt] = var2.possibleChildren[var7];
  116.                if (this.validateContent(var2.childCount, var2.curChildren) != -1) {
  117.                   var2.results[var7] = false;
  118.                }
  119.             }
  120.          }
  121.       }
  122.  
  123.       return -1;
  124.    }
  125.  
  126.    private void buildDFA() throws CMException {
  127.       ContentSpecNode var1 = new ContentSpecNode();
  128.       CMLeaf var2 = new CMLeaf(0, this.fEOCIndex);
  129.       this.fHeadNode = new CMBinOp(5, this.buildSyntaxTree(this.fDeclPool.getContentSpec(this.fElementIndex), var1), var2);
  130.       this.fEOCPos = this.fLeafCount;
  131.       var2.setPosition(this.fLeafCount++);
  132.       this.fLeafList = new CMLeaf[this.fLeafCount];
  133.       this.postTreeBuildInit(this.fHeadNode, 0);
  134.       this.fFollowList = new CMStateSet[this.fLeafCount];
  135.  
  136.       for(int var3 = 0; var3 < this.fLeafCount; ++var3) {
  137.          this.fFollowList[var3] = new CMStateSet(this.fLeafCount);
  138.       }
  139.  
  140.       this.calcFollowList(this.fHeadNode);
  141.       this.fElemMap = new int[this.fLeafCount];
  142.       this.fElemMapSize = 0;
  143.  
  144.       for(int var4 = 0; var4 < this.fLeafCount; ++var4) {
  145.          int var5 = this.fLeafList[var4].getElemIndex();
  146.  
  147.          int var6;
  148.          for(var6 = 0; var6 < this.fElemMapSize && this.fElemMap[var6] != var5; ++var6) {
  149.          }
  150.  
  151.          if (var6 == this.fElemMapSize) {
  152.             this.fElemMap[this.fElemMapSize++] = var5;
  153.          }
  154.       }
  155.  
  156.       int var20 = this.fLeafCount * 4;
  157.       CMStateSet[] var21 = new CMStateSet[var20];
  158.       this.fFinalStateFlags = new boolean[var20];
  159.       this.fTransTable = new int[var20][];
  160.       CMStateSet var7 = this.fHeadNode.firstPos();
  161.       int var8 = 0;
  162.       int var9 = 0;
  163.       this.fTransTable[var9] = this.makeDefStateList();
  164.       var21[var9] = var7;
  165.       ++var9;
  166.  
  167.       while(var8 < var9) {
  168.          var7 = var21[var8];
  169.          int[] var10 = this.fTransTable[var8];
  170.          this.fFinalStateFlags[var8] = var7.getBit(this.fEOCPos);
  171.          ++var8;
  172.          CMStateSet var11 = null;
  173.  
  174.          for(int var12 = 0; var12 < this.fElemMapSize; ++var12) {
  175.             if (var11 == null) {
  176.                var11 = new CMStateSet(this.fLeafCount);
  177.             } else {
  178.                var11.zeroBits();
  179.             }
  180.  
  181.             for(int var13 = 0; var13 < this.fLeafCount; ++var13) {
  182.                if (var7.getBit(var13) && this.fLeafList[var13].getElemIndex() == this.fElemMap[var12]) {
  183.                   var11.union(this.fFollowList[var13]);
  184.                }
  185.             }
  186.  
  187.             if (!var11.isEmpty()) {
  188.                int var14;
  189.                for(var14 = 0; var14 < var9 && !var21[var14].isSameSet(var11); ++var14) {
  190.                }
  191.  
  192.                if (var14 == var9) {
  193.                   var21[var9] = var11;
  194.                   this.fTransTable[var9] = this.makeDefStateList();
  195.                   ++var9;
  196.                   var11 = null;
  197.                }
  198.  
  199.                var10[var12] = var14;
  200.                if (var9 == var20) {
  201.                   int var15 = (int)((double)var20 * (double)1.5F);
  202.                   CMStateSet[] var16 = new CMStateSet[var15];
  203.                   boolean[] var17 = new boolean[var15];
  204.                   int[][] var18 = new int[var15][];
  205.  
  206.                   for(int var19 = 0; var19 < var20; ++var19) {
  207.                      var16[var19] = var21[var19];
  208.                      var17[var19] = this.fFinalStateFlags[var19];
  209.                      var18[var19] = this.fTransTable[var19];
  210.                   }
  211.  
  212.                   var20 = var15;
  213.                   var21 = var16;
  214.                   this.fFinalStateFlags = var17;
  215.                   this.fTransTable = var18;
  216.                }
  217.             }
  218.          }
  219.       }
  220.  
  221.       this.fEmptyContentIsValid = ((CMBinOp)this.fHeadNode).getLeft().isNullable();
  222.       this.fHeadNode = null;
  223.       this.fLeafList = null;
  224.       this.fFollowList = null;
  225.    }
  226.  
  227.    private final CMNode buildSyntaxTree(int var1, ContentSpecNode var2) throws CMException {
  228.       Object var3 = null;
  229.       this.fDeclPool.getContentSpecNode(var1, var2);
  230.       if (var2.type == 0) {
  231.          var3 = new CMLeaf(var2.type, var2.value, this.fLeafCount++);
  232.       } else {
  233.          int var4 = var2.value;
  234.          int var5 = var2.otherValue;
  235.          if (var2.type != 4 && var2.type != 5) {
  236.             if (var2.type == 2) {
  237.                var3 = new CMUniOp(var2.type, this.buildSyntaxTree(var4, var2));
  238.             } else if (var2.type == 1) {
  239.                var3 = new CMBinOp(4, this.buildSyntaxTree(var4, var2), new CMLeaf(0, this.fEpsilonIndex));
  240.             } else {
  241.                if (var2.type != 3) {
  242.                   throw new CMException(152);
  243.                }
  244.  
  245.                var3 = new CMBinOp(5, this.buildSyntaxTree(var4, var2), new CMUniOp(2, this.buildSyntaxTree(var4, var2)));
  246.             }
  247.          } else {
  248.             var3 = new CMBinOp(var2.type, this.buildSyntaxTree(var4, var2), this.buildSyntaxTree(var5, var2));
  249.          }
  250.       }
  251.  
  252.       return (CMNode)var3;
  253.    }
  254.  
  255.    private void calcFollowList(CMNode var1) throws CMException {
  256.       if (var1.type() == 4) {
  257.          this.calcFollowList(((CMBinOp)var1).getLeft());
  258.          this.calcFollowList(((CMBinOp)var1).getRight());
  259.       } else if (var1.type() == 5) {
  260.          this.calcFollowList(((CMBinOp)var1).getLeft());
  261.          this.calcFollowList(((CMBinOp)var1).getRight());
  262.          CMStateSet var5 = ((CMBinOp)var1).getLeft().lastPos();
  263.          CMStateSet var6 = ((CMBinOp)var1).getRight().firstPos();
  264.  
  265.          for(int var7 = 0; var7 < this.fLeafCount; ++var7) {
  266.             if (var5.getBit(var7)) {
  267.                this.fFollowList[var7].union(var6);
  268.             }
  269.          }
  270.  
  271.       } else if (var1.type() == 2) {
  272.          this.calcFollowList(((CMUniOp)var1).getChild());
  273.          CMStateSet var2 = var1.firstPos();
  274.          CMStateSet var3 = var1.lastPos();
  275.  
  276.          for(int var4 = 0; var4 < this.fLeafCount; ++var4) {
  277.             if (var3.getBit(var4)) {
  278.                this.fFollowList[var4].union(var2);
  279.             }
  280.          }
  281.  
  282.       } else if (var1.type() == 3 || var1.type() == 1) {
  283.          throw new CMException(157);
  284.       }
  285.    }
  286.  
  287.    private void dumpTree(CMNode var1, int var2) throws CMException {
  288.       for(int var3 = 0; var3 < var2; ++var3) {
  289.          System.out.print("   ");
  290.       }
  291.  
  292.       int var4 = var1.type();
  293.       if (var4 != 4 && var4 != 5) {
  294.          if (var1.type() == 2) {
  295.             System.out.print("Rep Node ");
  296.             if (var1.isNullable()) {
  297.                System.out.print("Nullable ");
  298.             }
  299.  
  300.             System.out.print("firstPos=");
  301.             System.out.print(var1.firstPos().toString());
  302.             System.out.print(" lastPos=");
  303.             System.out.println(var1.lastPos().toString());
  304.             this.dumpTree(((CMUniOp)var1).getChild(), var2 + 1);
  305.          } else if (var1.type() == 0) {
  306.             System.out.print("Leaf: (pos=" + ((CMLeaf)var1).getPosition() + "), " + this.fStringPool.toString(((CMLeaf)var1).getElemIndex()) + "(elemIndex=" + ((CMLeaf)var1).getElemIndex() + ") ");
  307.             if (var1.isNullable()) {
  308.                System.out.print(" Nullable ");
  309.             }
  310.  
  311.             System.out.print("firstPos=");
  312.             System.out.print(var1.firstPos().toString());
  313.             System.out.print(" lastPos=");
  314.             System.out.println(var1.lastPos().toString());
  315.          } else {
  316.             throw new CMException(157);
  317.          }
  318.       } else {
  319.          if (var4 == 4) {
  320.             System.out.print("Choice Node ");
  321.          } else {
  322.             System.out.print("Seq Node ");
  323.          }
  324.  
  325.          if (var1.isNullable()) {
  326.             System.out.print("Nullable ");
  327.          }
  328.  
  329.          System.out.print("firstPos=");
  330.          System.out.print(var1.firstPos().toString());
  331.          System.out.print(" lastPos=");
  332.          System.out.println(var1.lastPos().toString());
  333.          this.dumpTree(((CMBinOp)var1).getLeft(), var2 + 1);
  334.          this.dumpTree(((CMBinOp)var1).getRight(), var2 + 1);
  335.       }
  336.    }
  337.  
  338.    private int[] makeDefStateList() {
  339.       int[] var1 = new int[this.fElemMapSize];
  340.  
  341.       for(int var2 = 0; var2 < this.fElemMapSize; ++var2) {
  342.          var1[var2] = -1;
  343.       }
  344.  
  345.       return var1;
  346.    }
  347.  
  348.    private int postTreeBuildInit(CMNode var1, int var2) throws CMException {
  349.       var1.setMaxStates(this.fLeafCount);
  350.       if (var1.type() != 4 && var1.type() != 5) {
  351.          if (var1.type() == 2) {
  352.             var2 = this.postTreeBuildInit(((CMUniOp)var1).getChild(), var2);
  353.          } else {
  354.             if (var1.type() != 0) {
  355.                throw new CMException(157);
  356.             }
  357.  
  358.             if (((CMLeaf)var1).getElemIndex() != this.fEpsilonIndex) {
  359.                this.fLeafList[var2++] = (CMLeaf)var1;
  360.             }
  361.          }
  362.       } else {
  363.          var2 = this.postTreeBuildInit(((CMBinOp)var1).getLeft(), var2);
  364.          var2 = this.postTreeBuildInit(((CMBinOp)var1).getRight(), var2);
  365.       }
  366.  
  367.       return var2;
  368.    }
  369.  
  370.    static {
  371.       "<<CMNODE_EPSILON>>".intern();
  372.       "<<CMNODE_EOC>>".intern();
  373.    }
  374. }
  375.